
package Serveur;

import Client.I_ChatClient;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;


public class ServeurChat extends UnicastRemoteObject implements I_chat {
    
    private static final long serialVersionUID = 1L;
    //Nombre d'utilisateur maximum du serveur
    private int nb_utilisateur;
    //Taille maximale des fichier envoyés au serveur
    private int tailleFichier;
    //Liste des utilisateurs du chat
    public LinkedList <I_ChatClient> clients;
    //Historique des messages du chat 
    public ArrayList <String> history;
        
    public ServeurChat() throws RemoteException {
        super();
        Scanner sc = new Scanner(System.in); 

        //Fixe le nombre d'utilisateur maximal du serveur
        System.out.println("Veuillez indiquer le nombre d'utilisateur maximal sur le serveur que vous souhaitez : ");
        setNb_utilisateur(sc.nextInt());

        //Fixe la taille maximale des fichiers sur le serveur
        System.out.println("Veuillez indiquer la taille maximale (en ko) des fichiers sur le serveur : ");
        setTailleFichier(sc.nextInt());
        //Instancie la liste des utilisateurs du chat
        clients = new LinkedList<I_ChatClient>();
        //Instancie l'historique du chat
        history = new ArrayList<String>();
    }
    
    @Override
        public synchronized void connecter(I_ChatClient client) throws RemoteException {
            if(nbUtilisateursValide(clients)){
                clients.add(client); 
                //Affiche l'historique des messages
                if (!history.isEmpty()) {
                  for (int i = 0; i < history.size(); i++) {
                    client.recevoir(history.get(i), "", 'h');  
                  }  
                }
                envoyerMessage(" est entré dans le chat", client.getNomClient(), 'e');
            }
        }

        @Override
        public void deconnecter(I_ChatClient client) throws RemoteException {
          clients.remove(client); 
          envoyerMessage(" a quitté  le chat", client.getNomClient(), 'l');
        }
        
    @Override
        public synchronized void envoyerMessage(String message, String auteur, char mode) throws RemoteException {
            //Mise à jour de l'historique des messages
            if (mode == 's') {
                history.add(auteur + " dit " + message);
            }
            //Envoi du message à tous les utilisateurs
            for (int i = 0; i < clients.size(); i++){
                clients.get(i).recevoir(message, auteur, mode);
            }
        }
    
    @Override
        public LinkedList<I_ChatClient> clientsDisponibles() throws RemoteException{
            return this.clients;
        }
    
    @Override
        public void messagePrive(String message, String exp, String des, char mode) throws RemoteException{
            int i;
            i=chercherNom(des);
            clients.get(i).recevoir(message, exp, mode);
            
        }
        
     @Override
        public int chercherNom(String nom) throws RemoteException{
            int res=0;
            for(int j=0;j<clients.size();j++){
                if(clients.get(j).getNomClient().equals(nom)){
                    res=j;
                }
            }
            
            return res;
        }
        
        @Override
        public boolean UtilisateurValide(String nom) throws RemoteException{
            boolean rep=true;
            for(int i=0;i<clients.size();i++){
                if(clients.get(i).getNomClient().equalsIgnoreCase(nom)){
                    rep=false;
                }
            }
            return rep;
        }
        
        //Fonction permettant de voir si le nom d'utilisateur et son mot de passe sont coreecte
        //Et que l'utilisateur n'est pas déjà connecté
        @Override
        public String login() throws RemoteException{
           System.out.println("CCCCCCCCCCCCCCCCCCCC"); 
           boolean rep=true;
           //boolean rep2=true;
           String nom="";
           String mdp="";
           do{
                System.out.println("DDDDDDDDDDDDDDDDDD");
                System.out.println("Entrez votre nom d'utilisateur : ");
                Scanner forname = new Scanner(System.in);
                nom=forname.nextLine();
                //mdp=forname.nextLine();
                //rep2=verifLogin(nom, mdp);
                rep=UtilisateurValide(nom);
                if(!rep){
                    System.out.println("L'utilisateur est déjà connecté");
                }
                /*if(!rep2){
                    System.out.println("Mot de passe invalide ou nom d'utilisateur érroné !");
                    ajouterLog(nom, mdp);
                }*/
            }while(!rep);
            return nom;
        }

        @Override
        public boolean nbUtilisateursValide(LinkedList<I_ChatClient> liste) throws RemoteException{
            boolean valide = false;
            if(liste.size() > getNb_utilisateur()){
                try {
                    throw new Exception("Serveur complet");
                } 
                catch (Exception ex) {
                    Logger.getLogger(ServeurChat.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            else{
                valide = true;
            }
            return valide;
        }

        @Override
        public boolean tailleFichierValide(File fichier) throws RemoteException{
            boolean valide = false;
            if(fichier.length()/1024 > getTailleFichier()){
                try {
                    throw new Exception("Fichier trop volumineux");
                } 
                catch (Exception ex) {
                    Logger.getLogger(ServeurChat.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            else{
                valide = true;
            }
            return valide;
        }

        /** Retourne la taille maximale des fichiers qu'on peut envoyer sur le serveur
         * @return la taille max des fichiers en ko
         */
        public int getTailleFichier() {
            return tailleFichier;
        }

        /** Affecte la taille maximale des fichiers qu'on peut envoyer sur le serveur
         * @param nb_utilisateur la taille max des fichiers en ko
         */
        public void setTailleFichier(int tailleFichier) {
            this.tailleFichier = tailleFichier /1024;
        }

        /** Retourne le nombre d'utilisateur maximum du serveur
         * @return le nombre d'utilisateur max
         */
        public int getNb_utilisateur() {
            return nb_utilisateur;
        }

        /** Affecte le nombre d'utilisateur maximum du serveur
         * @param nb_utilisateur le nombre d'utilisateur max
         */
        public void setNb_utilisateur(int nb_utilisateur) {
            this.nb_utilisateur = nb_utilisateur;
        }
        
    @Override
	public void stockerChaine(String nomFichier, String chaine) throws RemoteException {
            //Génère le chemin où stocker le fichier dans le dossier exécutable
            String adressedufichier = "/home/c/cailleol/workspace/trunk/workspace/ExempleRMI/" + nomFichier;

	    try
	    {
                FileWriter fw = null;
            try {
                fw = new FileWriter(adressedufichier, false);
            } catch (IOException ex) {
                Logger.getLogger(Serveur.class.getName()).log(Level.SEVERE, null, ex);
            }
		BufferedWriter output = new BufferedWriter(fw);
                output.write(chaine);
		output.close();
		System.out.println("Fichier créé.");
	    }
	    catch(IOException ioe){
	    System.out.print("Erreur : ");
            ioe.printStackTrace();
	    }
        }
        
        @Override
	public void envoiFichier(String nomFichier, byte[] fichier) throws RemoteException {
           
            try {
                BufferedOutputStream bos;
                
                /**
                 * Récupère le chemin du fichier dans le dossier exécutable
                 */
                String adressedufichier = new java.io.File(nomFichier).getAbsolutePath();
                
                bos = new BufferedOutputStream(new FileOutputStream(new File(adressedufichier)));

                for (int i = 0 ; i < fichier.length ; i++) {
                bos.write((int)fichier[i]);
                }	 
                System.out.println("Fichier crée.");
                bos.close();
            }
                    
	    catch(IOException e) {
                 System.out.println(e + "Erreur lors de la lecture du fichier.");
            }
	}
    
    
}
